#include "storage_system.h"
#include "disk_io.h"
#include "cache_manager.h"
#include "page_manager.h"
#include "stats_monitor.h"
#include "catalog.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>

// Windows 平台特定头文件
#ifdef _WIN32
#include <direct.h>  // Windows 平台的目录操作头文件
#endif

// 全局模块实现
// 全局模块实例
static cache_manager_t* cache_manager = NULL;     // 缓存管理器实例
static page_manager_t* page_manager = NULL;       // 页面管理器实例
static stats_monitor_t* stats_monitor = NULL;     // 统计监视器实例
static char* data_directory = NULL;               // 数据目录路径

// 内部辅助函数声明
static storage_error_t flush_page_internal(page_id_t page_id);

// 初始化存储系统
// 参数：
//   data_dir - 数据目录路径
// 返回值：
//   STORAGE_OK表示成功，其他值表示失败类型
storage_error_t init_storage_system(const char* data_dir) {
    // 改进：更健壮的目录创建逻辑
    #ifdef _WIN32
    // 在Windows上创建目录
    int mkdir_result = _mkdir(data_dir);  // Windows使用_mkdir
    if (mkdir_result != 0 && errno != EEXIST) {
        fprintf(stderr, "ERROR: Failed to create directory %s - %s\n", data_dir, strerror(errno));
        return STORAGE_ERROR_IO;
    }
    #else
    // 在Unix/Linux上创建目录
    int mkdir_result = mkdir(data_dir, 0700);
    if (mkdir_result != 0 && errno != EEXIST) {
        fprintf(stderr, "ERROR: Failed to create directory %s - %s\n", data_dir, strerror(errno));
        return STORAGE_ERROR_IO;
    }
    #endif

    page_manager = page_manager_create();
    if (!page_manager) {
        return STORAGE_ERROR_IO;
    }

    // 新增：强制分配系统表使用的固定PID
    // 项目中 TABLES_PID=1, COLUMNS_PID=2，确保这些ID被分配
    page_manager_force_allocate(page_manager, 0); // 可能需要的页面
    page_manager_force_allocate(page_manager, 1); // 表信息页
    page_manager_force_allocate(page_manager, 2); // 列信息页

    cache_manager = cache_manager_create(CACHE_SIZE, CACHE_LRU);
    if (!cache_manager) {
        page_manager_destroy(page_manager);
        page_manager = NULL;
        return STORAGE_ERROR_IO;
    }

    // 修复：设置缓存管理器的数据目录
    cache_manager_set_data_directory(cache_manager, data_dir);

    // store data_directory if exists in this file
    if (data_directory) free(data_directory);
    data_directory = strdup(data_dir);

    return STORAGE_OK;
}

// 关闭存储系统
// 返回值：
//   STORAGE_OK表示成功
storage_error_t shutdown_storage_system() {
    // 刷新所有页面
    flush_all_pages();

    // 释放资源
    if (cache_manager) {
        cache_manager_destroy(cache_manager);
        cache_manager = NULL;
    }

    if (page_manager) {
        page_manager_destroy(page_manager);
        page_manager = NULL;
    }

    if (stats_monitor) {
        stats_monitor_destroy(stats_monitor);
        stats_monitor = NULL;
    }

    if (data_directory) {
        free(data_directory);
        data_directory = NULL;
    }

    return STORAGE_OK;
}

// 分配页面
page_id_t allocate_page() {
    if (!page_manager) {
        return UINT32_MAX;
    }
    return page_manager_allocate(page_manager);
}

// 释放页面
storage_error_t free_page(page_id_t page_id) {
    if (!page_manager) {
        return STORAGE_ERROR_INVALID;
    }

    // 从缓存中移除
    if (cache_manager) {
        cache_manager_remove(cache_manager, page_id);
    }

    // 从磁盘删除
    storage_error_t result = disk_delete_page(data_directory, page_id);
    if (result != STORAGE_OK) {
        return result;
    }

    // 向页面管理器释放
    return page_manager_free(page_manager, page_id);
}

// 直接读取页面(绕过缓存)
storage_error_t read_page(page_id_t page_id, uint8_t* buffer) {
    if (!page_manager_is_allocated(page_manager, page_id)) {
        return STORAGE_ERROR_NOT_FOUND;
    }
    return disk_load_page(data_directory, page_id, buffer);
}

// 直接写入页面(绕过缓存)
storage_error_t write_page(page_id_t page_id, const uint8_t* data) {
    if (!page_manager_is_allocated(page_manager, page_id)) {
        return STORAGE_ERROR_NOT_FOUND;
    }
    return disk_save_page(data_directory, page_id, data);
}

// 通过缓存读取页面
storage_error_t get_page(page_id_t page_id, uint8_t* buffer) {
    if (!page_manager_is_allocated(page_manager, page_id)) {
        return STORAGE_ERROR_NOT_FOUND;
    }

    if (!cache_manager) {
        return disk_load_page(data_directory, page_id, buffer);
    }

    return cache_manager_get(cache_manager, page_id, buffer);
}

// 刷新页面到磁盘
storage_error_t flush_page(page_id_t page_id) {
    return flush_page_internal(page_id);
}

// 内部刷新页面实现
static storage_error_t flush_page_internal(page_id_t page_id) {
    if (!cache_manager) {
        return STORAGE_OK; // 没有缓存，无需刷新
    }

    return cache_manager_flush(cache_manager, page_id);
}

// 刷新所有页面
storage_error_t flush_all_pages() {
    if (!cache_manager) {
        return STORAGE_OK;
    }

    return cache_manager_flush_all(cache_manager);
}

// 获取缓存命中次数
uint32_t get_cache_hits() {
    return cache_manager ? cache_manager_get_hits(cache_manager) : 0;
}

// 获取缓存未命中次数
uint32_t get_cache_misses() {
    return cache_manager ? cache_manager_get_misses(cache_manager) : 0;
}

// 打印缓存统计信息
void print_cache_stats() {
    uint32_t hits = get_cache_hits();
    uint32_t misses = get_cache_misses();
    uint32_t size = cache_manager ? cache_manager_get_size(cache_manager) : 0;
    uint32_t capacity = cache_manager ? cache_manager_get_capacity(cache_manager) : 0;

    stats_monitor_print_cache_stats(hits, misses, size, capacity);
}

// 打印替换日志
void print_replacement_log() {
    if (stats_monitor) {
        stats_monitor_print_replacement_log(stats_monitor);
    }
}

// 修改为
int init_storage_system_with_catalog(const char *data_dir, void* catalog_param) {
    // 将void*转换为Catalog*
    Catalog* catalog = (Catalog*)catalog_param;
    
    int result = init_storage_system(data_dir);
    if (result != STORAGE_OK) {
        return result;
    }
    
    // 引导系统表
    if (catalog_bootstrap() != 0) {
        return STORAGE_ERROR_IO; // 使用已有的错误码
    }
    
    // 从系统表加载表结构到内存目录
    if (catalog) {
        if (catalog_load_all_tables(catalog) != 0) {
            return STORAGE_ERROR_IO; // 使用已有的错误码
        }
    }
    
    return STORAGE_OK;
}

// 确保所有数据都持久化的增强版本
storage_error_t shutdown_storage_system_ensure_persistence() {
    // 刷新所有脏页面到磁盘
    storage_error_t result = flush_all_pages();
    
    // 调用原始的关闭函数
    if (result == STORAGE_OK) {
        result = shutdown_storage_system();
    }
    
    return result;
}